package util;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;

import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

/**
 * xsd数据结构检查工具类
 * 该类提供了两个工具方法，一个用于验证 XML 文件是否符合 XSD 模式，另一个用于将 JSON 字符串转换为 XML 文件。
 */
public class XSDUtil {

    /**
     * 验证 XML 文件是否符合指定的 XSD 模式
     * @param xmlFile 待验证的 XML 文件
     * @param xsdFile 用于验证的 XSD 模式文件
     * @return 如果 XML 文件符合 XSD 模式，返回 true；否则返回 false
     */
    public static boolean validateXMLWithXSD(File xmlFile, File xsdFile) {
        try {
            // 创建 SchemaFactory 实例，指定使用 W3C XML Schema 语言标准。
            // XMLConstants.W3C_XML_SCHEMA_NS_URI 是 W3C 定义的 XML Schema 的命名空间 URI
            SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            // 从指定的 XSD 文件加载 XML Schema 信息，创建 Schema 对象
            Schema schema = factory.newSchema(xsdFile);
            // 根据加载的 Schema 创建一个 Validator 实例，用于执行 XML 文件的验证操作
            Validator validator = schema.newValidator();
            // 将 XML 文件封装为一个 Source 对象，方便 Validator 进行处理
            Source source = new StreamSource(xmlFile);
            // 调用 Validator 的 validate 方法对 XML 文件进行验证
            validator.validate(source);
            return true;
        } catch (Exception e) {
            // 若验证过程中出现异常，打印异常信息
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据 String 内容（JSON 字符串）转换为 XML 文件
     * @param content 输入的 JSON 字符串
     * @return 生成的 XML 文件对象；若过程中出现异常，返回 null
     * @throws IOException 当文件操作或 JSON/XML 处理出现 I/O 异常时抛出
     */
//    public static File convertStringToFile(String content) throws IOException {
//        try {
//            // 1. 使用 Jackson 解析 JSON 字符串
//            ObjectMapper jsonMapper = new ObjectMapper();
//            JsonNode jsonNode = jsonMapper.readTree(content);
//
//            // 2. 使用 Jackson 的 XmlMapper 将 JSON 转换为 XML
//            XmlMapper xmlMapper = new XmlMapper();
//            xmlMapper.configure(com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true); // 添加 XML 声明
//            xmlMapper.configure(com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator.Feature.WRITE_XML_1_1, true); // 使用 XML 1.1
//            // 4. 将 XML 写入文件
//            File xmlFile = new File("componentMaintReport.xml");
//            xmlMapper
//                    .writer()
//                    .withRootName("componentMaintReport")
//                    .withDefaultPrettyPrinter()
//                    .writeValue(xmlFile, jsonNode.get("componentMaintReport"));
//            return xmlFile;
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return null;
//    }

    public static File convertStringToFile(String content) throws IOException {
        try {
            // 1. 使用 Jackson 解析 JSON 字符串
            ObjectMapper jsonMapper = new ObjectMapper();
            JsonNode jsonNode = jsonMapper.readTree(content);
            JsonNode componentMaintReportNode = jsonNode.get("componentMaintReport");

            // 获取版本号
            String version = "0.1"; // 默认版本
            if (componentMaintReportNode.has("version")) {
                version = componentMaintReportNode.get("version").asText();
                // 移除 version 字段，因为它将作为属性
                ((ObjectNode) componentMaintReportNode).remove("version");
            }

            // 2. 使用 Jackson 的 XmlMapper 将 JSON 转换为 XML
            XmlMapper xmlMapper = new XmlMapper();
            xmlMapper.configure(com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
            xmlMapper.configure(com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator.Feature.WRITE_XML_1_1, true);

            // 3. 将 XML 写入文件
            File xmlFile = new File("componentMaintReport.xml");
            String xmlContent = xmlMapper
                    .writer()
                    .withRootName("componentMaintReport")
                    .withDefaultPrettyPrinter()
                    .writeValueAsString(componentMaintReportNode);

            // 4. 添加 version 属性到根元素
            xmlContent = xmlContent.replace(
                    "<componentMaintReport>",
                    "<componentMaintReport version=\"" + version + "\">"
            );

            // 5. 写回文件
            Files.write(xmlFile.toPath(), xmlContent.getBytes());
            return xmlFile;

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


}
